package com.lbd.system.service.impl;


import java.util.Date;
import java.util.List;
import java.util.Map;

import com.lbd.project.bean.TargetInfo;
import com.lbd.project.dao.TargetRepository;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.hibernate.SQLQuery;
import org.hibernate.transform.Transformers;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import com.lbd.base.service.BaseServiceImpl;
import com.lbd.commons.ApplicationContextUtil;
import com.lbd.commons.event.EventState;
import com.lbd.system.bean.BindCard;
import com.lbd.system.bean.User;
import com.lbd.system.bean.UserAuthentication;
import com.lbd.system.bean.UserMoneyStatistics;
import com.lbd.system.controller.vo.UserVo;
import com.lbd.system.dao.BindCardRepository;
import com.lbd.system.dao.UserMoneyStatisticsRepository;
import com.lbd.system.dao.UserRepository;
import com.lbd.system.event.UserRegisterEvent;
import com.lbd.system.service.UserService;

import javax.persistence.Query;

/**
 * Created by WangYajie on 2016/9/12.
 */
@Service
@Transactional
public class UserServiceImpl extends BaseServiceImpl<User, UserRepository> implements UserService {
    private final Logger log = Logger.getLogger(this.getClass());
    @Autowired
    UserRepository userRepository;
    @Autowired
    BindCardRepository bindCardRepository;
    @Autowired
    UserMoneyStatisticsRepository userMoneyStatisticsRepository;
    @Autowired
    private TargetRepository targetRepository;


    @Override
    public void save(User user) {
        userRepository.save(user);
        //发布事件
        ApplicationContextUtil.publishEvent(new UserRegisterEvent(this, user, EventState.SUCCESS, "注册成功"));
    }

    @Override
    public Specification<User> getSpecification(User user) {
        return null;
    }

    @Override
    public String buildJpql(User u, Map<String, Object> parameter) {

        UserVo user = (UserVo) u;
//select new User(t.id,t.telephone,t.name,t.idCard,t.email,t.plantFrom,t.createdDate,t.state,t.type)
        StringBuilder jpqlBuilder = new StringBuilder("   from  User t   ");

        if (user != null) {
            if (StringUtils.isNotBlank(user.getTelephone())) {
                jpqlBuilder.append(" and  telephone like :telephone");
                parameter.put("telephone", "%" + user.getTelephone() + "%");
            }
            if (StringUtils.isNotBlank(user.getName())) {
                jpqlBuilder.append(" and  name like :name");
                parameter.put("name", "%" + user.getName() + "%");
            }
            if (StringUtils.isNotBlank(user.getPlantFrom())) {
                jpqlBuilder.append(" and  plantFrom like :plantFrom");
                parameter.put("plantFrom", user.getPlantFrom());
            }
            if (user.getBeginTime() != null) {
                jpqlBuilder.append(" and  createdDate > :beginTime");
                parameter.put("beginTime", user.getBeginTime());
            }
            if (user.getEndTime() != null) {
                jpqlBuilder.append(" and  createdDate < :endTime");
                parameter.put("endTime", user.getEndTime());
            }
            //是否实名
            if (StringUtils.isNotBlank(user.getAuthRealName())) {
                String isAuthentication = "01".equals(user.getAuthRealName()) ? "in" : "not in";
                jpqlBuilder.append(" and id " + isAuthentication + " ( select userId from UserAuthentication where type = ");
                jpqlBuilder.append(UserAuthentication.AUTH_REAL_NAME);
                jpqlBuilder.append(" )");
            }
            //是否绑卡
            if (StringUtils.isNotBlank(user.getAuthBindCard())) {
                String isAuthentication = "01".equals(user.getAuthBindCard()) ? "in" : "not in";
                jpqlBuilder.append(" and id " + isAuthentication + " ( select userId from UserAuthentication where type = ");
                jpqlBuilder.append(UserAuthentication.AUTH_BIND_CARD);
                jpqlBuilder.append(" )");
            }
            if (user.getInvestState() != null) {
                jpqlBuilder.append(" and  investState = :investState");
                parameter.put("investState", user.getInvestState());
            }
            if (user.getType() != null) {
                jpqlBuilder.append(" and  type = :type");
                parameter.put("type", user.getType());
            }
        }
        jpqlBuilder.append(" order by createdDate desc");
        return jpqlBuilder.toString();
    }

    @Override
    public void disableUser(String id) {
        userRepository.disableUser(id, new Date());
    }

    @Override
    public void restPassword(String id) {
        String telephone = userRepository.findOne(id).getTelephone();
        String password = telephone.substring(telephone.length() - 6);
        password = DigestUtils.md5Hex(password).toUpperCase();
        userRepository.restPassword(id, password);
    }

    @Override
    public User findById(String id) {
        User user = userRepository.findOne(id);
        //绑定银行卡信息
        List<BindCard> bindCards = bindCardRepository.findByUserId(id);
        if (!CollectionUtils.isEmpty(bindCards)) {
            user.setBindCard(bindCards.get(0));
            user.setIfOpenFast("是");
        } else {
            user.setIfOpenFast("否");
        }
        //设置资金明细
        UserMoneyStatistics moneyStatistics = userMoneyStatisticsRepository.findByUserId(id);
        user.setAmountStatistics(moneyStatistics);
        if (moneyStatistics != null) {
            //设置待还总额
            moneyStatistics.setDueRepaymentSum(moneyStatistics.getDueRepayCapital().add(moneyStatistics.getDueRepayInterest()));
        }

        return user;
    }

    @Override
    public void enableUser(String id) {
        userRepository.enableUser(id);
    }

    /**
     * 满标后，变更用户类型
     *
     * @param targetId
     */
    @Override
    public void updateUserType(String targetId) {
        //变更用户类型
        TargetInfo targetInfo = targetRepository.findById(targetId);
        //根据标的查询借款用户-借款人
        User user = userRepository.findByTelephone(targetInfo.getTelephone());
        if (user.getType() == null) {
            user.setType(User.TYPE_BORROWER);
        } else if (user.getType() == User.TYPE_INVESTOR) {
            user.setType(User.TYPE_BOTHTYPE);
        }
        userRepository.save(user);
        //根据标的对应订单查询投资用户-投资人
        String sql = "select DISTINCT u.id,u.type from `user` u,`order` o where o.user_id=u.id and o.target_id=:targetId ";
        Query nativeQuery = em.createNativeQuery(sql);
        nativeQuery.unwrap(SQLQuery.class).setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP);
        nativeQuery.setParameter("targetId", targetId);
        List<Map> users = nativeQuery.getResultList();
        users.stream().forEach(investor -> {
            if (investor.get("type") == null) {
                userRepository.updateTypeById((String) investor.get("id"), User.TYPE_INVESTOR);
            } else if ((int) investor.get("type") == User.TYPE_BORROWER) {
                userRepository.updateTypeById((String) investor.get("id"), User.TYPE_BOTHTYPE);
            }
        });
    }

}